import numpy as np
import matplotlib.pyplot
import scipy.special as sp

class NeuralNetwork:

    def __init__(self, n_input, n_hidden, n_output, lr):
        self.n_input = n_input
        self.n_hidden = n_hidden
        self.n_output = n_output
        self.lr = lr

        # 初始化随机权重，此处范围为（-0.5，0.5）但是没有考虑可能为0的情况，需注意
        # W1,2 表示前一层的第一个到下一层的第二个的权重，计算是Y = WI，也就是说W的
        # 每一行是不同input的权重， 每一行对应的是同样的hidden
        self.Wih = np.random.rand(self.n_hidden, self.n_input) - 0.5
        self.Who = np.random.rand(self.n_output, self.n_hidden) - 0.5

        self.active_fun = sp.expit

        '''
        # 比较复杂的正态分布式取法
        self.Wih = np.random.normal(0.0, pow(self/n_hidden, -0.5), (self.n_hidden, self.n_input))
        self.Who = np.random.normal(0.0, pow(self/n_output, -0.5), (self.n_output, self.n_hidden))
        '''

    def train(self, x, target):
        target = np.expand_dims(target, axis=1)
        predict_h = self.forward_h(x)
        predict_o = self.forward_o(predict_h)
        error_o = target - predict_o
        error_h = self.Who.T.dot(error_o)

        self.Who += self.lr*np.dot(error_o*predict_o*(1-predict_o), predict_h.T)
        self.Wih += self.lr*np.dot(error_h*predict_h*(1-predict_h), np.expand_dims(x,axis=0))

    def forward_h(self, x):
        x = np.expand_dims(x, axis=1)
        return self.active_fun(np.dot(self.Wih,x))

    def forward_o(self, x):
        # print(x)
        return self.active_fun(np.dot(self.Who,x))

def mian():

    nerualnetwork = NeuralNetwork(3,3,3,0.5)
    inputs = np.array([1,2,3])
    print(nerualnetwork.query(inputs))


if __name__ == "__main__":
    mian()